home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
184_01
/
fl3.mac
< prev
next >
Wrap
Text File
|
1980-01-01
|
13KB
|
535 lines
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;
;This file contains the third of three patches to the
;source code for FLTLIB to enable use of the AMD9511
;(Intel 8231A) for floating point multiply/divide
;and MATHLIB functions.
;N.T.Carnevale 8/84.
;
;
;See accompanying documentation. Other useful information
;is in my article "Faster floating point math," which appeared
;on pp.46-54 of the Nov/Dec 1985 issue of Micro/Systems Journal.
;
;Use the following code to replace the source of the FLTLIB
;section of FLOATLIB.ASM from the line labelled fmult3:
;through the line just before label pophrt:
;
;
;
CR EQU 0DH
LF EQU 0AH
BDOS EQU 5
BOOT EQU 0
PSTRNG EQU 9
;
;
;send message to console
PRMSG:
PUSH PSW
PUSH B
PUSH D
PUSH H
MVI C,PSTRNG
CALL BDOS
POP H
POP D
POP B
POP PSW
RET
;
;**************************************************************
;
;
;Port addresses
;
BASE EQU 050H ;base address of Compupro SS1 board
CREG EQU BASE+9 ;location of 9511's control & data ports
DREG EQU BASE+8
;
;
;FPP error codes
;
ERRBITS EQU 1EH ;the status register's error bits
OVRFLO EQU 2 ;overflow
UNRFLO EQU 4 ;underflow
NEGARG EQU 8 ;negative argument to sqrt or log function
DIVZER EQU 10H ;divide by zero
TOOBIG EQU 18H ;arg of asin, acos, or exp too big
;
;
;FPP command codes
;
FMUL EQU 12H
FDIV EQU 13H
XCHF EQU 19H ;swap top two locations in fpp's stack
FSQRT EQU 1
FSIN EQU 2
FCOS EQU 3
FTAN EQU 4
FASIN EQU 5
FACOS EQU 6
FATAN EQU 7
FLOG EQU 8 ;log base 10
FLN EQU 9 ;natural logarithm
FEXP EQU 0AH ;e^x
FPWR EQU 0BH ;x^y
;
;**************************************************************
;**************************************************************
;
;
;note: timing indicated for some of the following
;
;This block converts c80 float in BD to FPP format, then loads it into FPP.
;If out of range for FPP, aborts with warning.
;
;Data format conversion routine C2AMD--
;converts c80's float to amd's fp format.
;Based on suggestions by J.Shook, Electronics Lab, Dept.of Chemistry,
;SUNY Stony Brook
;
;Floating point formats
;----------------------
;C80 stores floats as:
; mantissa sign in C7
; mantissa = 24 bit two's complement in CDE,
; with bit 23 assumed = 1.
; exponent is added to 128 (80H) and stored in B.
; If the number is 0, B=0.
;
;FPP stores floats as:
; mantissa sign in B7
; mantissa = 24 bit two's complement in CDE,
; with bit 23 = 1. However,
; the value 0 is represented by BD=0.
; exponent sign in B6
; exponent in B5-B0 (only 6 bits).
;
;
;Call with value to convert in BD.
C2AMD:
MOV A,B ; 4
ORA A ; 4
JZ FPPZERO ;10--B=0 implies x=0
;does exponent lie in FPP's range?
CPI 64+80H ; 7
JNC EXPHI ;10--exceeds 2^63
CPI -64+80H ; 7
JC EXPLO ;10--smaller than 2^-64
;exponent ok, proceed
SUI 80H ; 7--corrects exponent
ANI 7FH ; 7--mask out hi bit of B
MOV B,A ; 4-- and save til later
MOV A,C ; 4
ANI 80H ; 7--isolate mantissa sign bit
ORA B ; 4--fix mantissa sign bit for FPP
MOV B,A ; 4--done with B
;take care of C
MVI A,80H ; 7
ORA C ; 4--set hi bit of C
MOV C,A ; 4
JMP LOADFPP ;10--put data in FPP
;114 t cycles @ 4mHz = 28.5usec
;
FPPZERO: ;x=0
XRA A
MOV C,A
MOV D,A
MOV E,A
;a short cut, time not calculated
;fall through to next routine
;
;
;Data transfer routine
;LOADFPP puts BD into fpp
LOADFPP:
MOV A,E ; 4
OUT DREG ;11
MOV A,D ; 4
OUT DREG ;11
MOV A,C ; 4
OUT DREG ;11
MOV A,B ; 4
OUT DREG ;11
RET ;10
;70 t cycles = 17.5usec
;
;TOTAL TIME for C2AMD & LOADFPP = 46usec
;
;**************************************************************
;
;
;C2AMD found float to be out of range for FPP--warn & abort
EXPHI:
LXI D,HIMSG
JMP ERREXIT
EXPLO:
LXI D,LOMSG
ERREXIT:
CALL PRMSG
JMP BOOT ;bail out!
;
;
HIMSG: DB CR,LF,'float --> FPP exponent overflow ( > 2^63)$'
LOMSG: DB CR,LF,'float --> FPP exponent underflow ( < 2^-64)$'
;
;**************************************************************
;**************************************************************
;
;
;
;FLD1 gets 1 float from the stack, puts it into fpp,
;and DOES NOT restore stack. Called by "intrinsic"
;float arithmetic operations, e.g. fpmul and fpdiv.
FLD1:
POP H ;10--return addr for this block
SHLD RETADR ;16
POP H ;10--return addr for calling function
POP D ;10
POP B ;10--BD = argument
CALL C2AMD ;17--convert format & load FPP
;
PUSH H ;11--restore return address of calling function
LHLD RETADR ;16--return to calling function
PCHL ; 4-- without disturbing stack
;104 t cycles = 26usec, + 46 for C2AMD = 72usec
;
;**************************************************************
;
;
;FLOAD1 gets 1 float from the stack, puts it into fpp,
;and restores stack for c80. Called by "user-defined"
;functions, not by fpmul or fpdiv.
FLOAD1:
POP H ;10--return addr for this block
SHLD RETADR ;16
POP H ;10--return addr for calling function
POP D ;10
POP B ;10--BD = argument
CALL C2AMD ;17--convert format & load FPP
;fix stack for c80
PUSH H ;11
PUSH H ;11
PUSH H ;11--restore return address of calling function
LHLD RETADR ;16--return to calling function
PCHL ; 4-- without disturbing stack
;126 t cycles = 31.5usec, + 46 for C2AMD = 77.5usec
;
;**************************************************************
;
;
;FLOAD2 gets 2 floats from the stack, puts them into fpp,
; and restores the stack for c80
FLOAD2:
POP H ;10--return addr for this block
SHLD RETADR ;16
POP H ;10--return addr for calling function
POP D ;10
POP B ;10--BD = second argument
CALL C2AMD ;17--convert format & load FPP
POP D ;10
POP B ;10--BD = first argument
CALL C2AMD ;17
;fix stack for c80
PUSH H ;11 x 5 = 55
PUSH H
PUSH H
PUSH H
PUSH H ;restore return address of calling function
LHLD RETADR ;16--return to calling function
PCHL ; 4-- without disturbing stack
;185 t cycles = 46.25usec, + 2 * 46 (for C2AMD) = 138.25usec
;
RETADR: DS 2 ;used by all FPP load routines
;
;**************************************************************
;**************************************************************
;
;
;
;fpmask() allows the user to specify which error bits
;are tested for error detection. The argument to fpmask
;becomes the ERRMASK that is ANDed with the status word
;to detect a hardware (FPP) error.
PUBLIC fpmask
fpmask:
POP H ;return address
POP B ;argument
PUSH B ;fix stack
PUSH H
MOV A,C ;get the user-specified error mask
AN╔ ERRBIT╙ ╗ anΣ masδ ou⌠ al∞ bu⌠ thσ genuinσ erro≥ bits
STA ERRTEST+1
RET
;
;**************************************************************
;
;
;FPP Error handling routine
;print message according to what sort of error occurred
FPERR:
LXI D,EMSG0
CALL PRMSG ;print general message
MOV C,A ;save error code
MVI B,MSGPTR-ETYPES ;# of codes to check
LXI H,ETYPES ;M=first code in the list
LXI D,MSGPTR ;(DE) = address that contains
; location of message for first error code
ERCHEK:
ANA M
JMP ERMATCH
MOV A,C ;restore error code
INX H ;advance to next code and message
INX D
INX D
DCR B
JNZ ERCHEK ;more codes to test
;should never fall through, but if it does, will print 'huh?'
;
ERMATCH:
XCHG ;(HL) holds address of error message
MOV E,M
INX H
MOV D,M
JMP ERREXIT
;
;
EMSG0: DB CR,LF,,LF,'FPP error: $'
EMSG1: DB 'overflow$'
EMSG2: DB 'underflow$'
EMSG3: DB 'sqrt or log of negative number$'
EMSG4: DB 'divide by 0$'
EMSG5: DB 'argument of asin, acos, or exp too large$'
EMSGX: DB 'huh?$' ;should never occur!
;
;
ETYPES: DB OVRFLO,UNRFLO,TOOBIG,NEGARG,DIVZER
MSGPTR: DW EMSG1,EMSG2,EMSG5,EMSG3,EMSG4,EMSGX
;
;**************************************************************
;**************************************************************
;
;
;Next come the hardware floating point routines themselves.
;Thσ multiplcatio